package top.rainf.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.rainf.constants.AttributeConstants;
import top.rainf.domain.dto.UserFullInfo;
import top.rainf.domain.vo.UserPersonalInfo;
import top.rainf.service.IEmailService;
import top.rainf.service.ILoginService;
import top.rainf.service.IUserBaseInfoService;
import top.rainf.service.IUserPersonalInfoService;
import top.rainf.support.Result;
import top.rainf.support.TokenGenerator;
import top.rainf.support.VerifyCodeGenerator;
import top.rainf.util.CookieSetter;
import top.rainf.util.StringUtil;
import top.rainf.domain.vo.UserBaseInfo;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author 星环
 * @date 2023/5/6 13:50:04
 * @description 登录
 */
@RestController
//@CrossOrigin(origins={"localhost:8848","127.0.0.1:8848"})
@RequestMapping("/login")
public class LoginController {
    @Autowired
    ILoginService loginService;

    @Autowired
    IEmailService emailService;

    @Autowired
    IUserBaseInfoService userBaseInfoService;

    @Autowired
    IUserPersonalInfoService userPersonalInfoService;

    /**
     * 登录
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("/login")
    public Result login(HttpServletRequest request,HttpServletResponse response,
                        String username, String password,
                        @RequestParam("verify_code")                    String code,
                        @SessionAttribute(AttributeConstants.REAL_CODE) String realCode
                        ){

        UserBaseInfo res = loginService.login(username, password,code,realCode);
        if(res != null){
            //登录成功
            //生成用户的token，放进session中
            String token = TokenGenerator.genToken(res.getId(),res.getPassword());
            CookieSetter cookieSetter = new CookieSetter(request,response);
            cookieSetter.setSessionAttr(AttributeConstants.LOGIN_TOKEN,token);
            return Result.success("登录成功",res);
        }else {
            return Result.fail("登录失败");
        }
    }

    @RequestMapping("/checkLogin")
    public Result checkLogin( @SessionAttribute(value = AttributeConstants.LOGIN_TOKEN,required = false) String token){
        if(token == null){
            return Result.fail("用户未登录");
        }
        int userIdFromToken = TokenGenerator.getUserIdFromToken(token);
        UserBaseInfo baseInfo = userBaseInfoService.getOneById(userIdFromToken);
        UserPersonalInfo userPersonalInfo = userPersonalInfoService.getOneById(userIdFromToken);
        UserFullInfo fullInfo = new UserFullInfo(baseInfo,userPersonalInfo);
        if(baseInfo == null){
            return Result.success("用户未登录");
        }
        return Result.success().addObj("user",fullInfo);
    }

    @RequestMapping("/logout")
    public Result logout(HttpServletRequest request,HttpServletResponse response){
        //把resp的cookie删除，request的状态删除
        request.getSession().removeAttribute(AttributeConstants.LOGIN_TOKEN);
        return Result.success();
    }


    /**
     * 访问这个接口，需要填入需要重置的用户名和邮箱，获得验证码后填入验证码，该端口会把用户名和验证码混合，
     * 把混合后的凭证存入session
     * 之后用户需要点击邮箱中的网页，该网页向后端请求要验证，后端根据凭证，
     * @param request -
     * @param username 用户名
     * @param email 邮箱
     * @param realCode 验证码
     * @return 把凭证放进session
     */
    @RequestMapping("/reset-password-validate")
    public Result resetPasswordValidate(HttpServletRequest request, HttpServletResponse response, String username, String email,
                                        @RequestParam("verify_code") String verifyCode,
                                        @SessionAttribute("real_code") String realCode
                                        ) {
        //先验证验证码是否正确
        if (!loginService.verifyCaptcha(verifyCode, realCode)) {
            return Result.fail("验证码不正确，请重新输入");
        }
        //将username和邮箱存入session
        CookieSetter cookieSetter = new CookieSetter(request, response);
        cookieSetter.setSessionAttr("username",username);
        cookieSetter.setSessionAttr("email",email);
        return Result.success("请求成功！");
    }

    /**
     * 重置密码，必须在session里存有token和验证码，就是{@link LoginController#resetPasswordValidate(HttpServletRequest, String, String, String, String)}
     * @param username 要修改密码的用户名
     * @return 是否成功
     */

    @RequestMapping("/reset-password-email")
    public Result sendResetEmail(HttpServletRequest request,HttpServletResponse response,
                                 @SessionAttribute("email") String email,
                                 @SessionAttribute("username")String username){
        String code = VerifyCodeGenerator.generateVerifyCode(6);
        CookieSetter cookieSetter = new CookieSetter(request,response);
        emailService.sendEmail(email,"@=语扉论坛=@重置密码","您正在重置"+username + "的密码，请输入这个验证码：" + code);
        cookieSetter.setSessionAttr(AttributeConstants.REAL_CODE,code);
        return Result.success();
    }

    @RequestMapping("/reset-password")
    public Result resetPassword(HttpServletRequest request,
                                @SessionAttribute("username") String username,@RequestParam("new_password") String newPassword,
                                @SessionAttribute(AttributeConstants.REAL_CODE) String realCode){
        //先验证token是否存在
        if(StringUtil.isNullOrEmpty(realCode) || StringUtil.isNullOrEmpty(username)){
            return Result.fail("信息已经过期");
        }
        //重置密码
        boolean succ = userBaseInfoService.resetPasswordByUsername(username, newPassword);
        //删除token等验证信息。
        request.getSession().removeAttribute(AttributeConstants.RESET_PASSWORD_TOKEN);
        request.getSession().removeAttribute(AttributeConstants.REAL_CODE);
        return succ ? Result.success("重置密码成功") : Result.fail("重置密码失败");
    }
}
